package com.rchou.sts.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import static javax.persistence.GenerationType.IDENTITY;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityResult;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.SqlResultSetMapping;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.Version;

import org.hibernate.annotations.Type;
import org.joda.time.DateTime;
import org.springframework.data.domain.Auditable;

@Entity
@Table(name = "student")
@NamedQueries({
	@NamedQuery(name="Student.findAll", query="SELECT s FROM Student s"),
	@NamedQuery(name="Student.findById", query="SELECT DISTINCT s FROM Student s LEFT JOIN FETCH s.levels l WHERE s.id = :id"),
	@NamedQuery(name="Student.findAllWithDetail", query="SELECT DISTINCT s FROM Student s LEFT JOIN FETCH s.levels l")
})
@SqlResultSetMapping(
		name="studentResult",
		entities=@EntityResult(entityClass=Student.class)
)
public class Student implements Auditable<String, Long>, Serializable
{
	@Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "ID")
	private Long id;
	
	@Version
	@Column(name = "VERSION")
	private int version;
	
	@Column(name = "FIRST_NAME")
	private String firstName;
	
	@Column(name = "LAST_NAME")
	private String lastName;
	
	@Column(name = "ADDRESS")
	private String address;
	
	@Column(name = "PHONE")
	private String phone;
	
	@Column(name = "EMAIL")
	private String email;
	
	@Column(name = "PARENT_FIRST_NAME")
	private String parentFirstName;
	
	@Column(name = "PARENT_LAST_NAME")
	private String parentLastName;
	
	@OneToMany(mappedBy = "student", cascade=CascadeType.ALL, orphanRemoval=true, fetch=FetchType.LAZY)
	private List<Level> levels = new ArrayList<Level>();
	
	// Audit field
	@Column(name = "CREATED_BY")
	private String createdBy;
	@Column(name = "CREATED_DATE")
	@Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
	private DateTime createdDate;
	@Column(name = "LAST_MODIFIED_BY")
	private String lastModifiedBy;
	@Column(name = "LAST_MODIFIED_DATE")
	@Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
	private DateTime lastModifiedDate;
	
	public Long getId() 
	{
		return id;
	}

	public void setId(Long id) 
	{	
		this.id = id;
	}
	
	public int getVersion() 
	{
		return this.version;
	}
	
	public void setVersion(int version) 
	{
		this.version = version;
	}
	
	public String getFirstName() 
	{
		return this.firstName;
	}
	
	public void setFirstName(String firstName) 
	{
		this.firstName = firstName;
	}
	
	public String getLastName() 
	{
		return this.lastName;
	}
	
	public void setLastName(String lastName) 
	{
		this.lastName = lastName;
	}
	
	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getParentFirstName() {
		return parentFirstName;
	}

	public void setParentFirstName(String parentFirstName) {
		this.parentFirstName = parentFirstName;
	}

	public String getParentLastName() {
		return parentLastName;
	}

	public void setParentLastName(String parentLastName) {
		this.parentLastName = parentLastName;
	}

	public List<Level> getLevels() 
	{
		return levels;
	}

	public void setLevels(List<Level> levels) 
	{
		this.levels = levels;
	}
	
	public void addLvlHistory(Level level)
	{
		level.setStudent(this);
		getLevels().add(level);
	}
	
	public String getCreatedBy() 
	{
		return createdBy;
	}

	public void setCreatedBy(String createdBy) 
	{
		this.createdBy = createdBy;
	}

	public DateTime getCreatedDate() 
	{
		return createdDate;
	}

	public void setCreatedDate(DateTime createdDate) 
	{
		this.createdDate = createdDate;
	}

	public String getLastModifiedBy() 
	{
		return lastModifiedBy;
	}

	public void setLastModifiedBy(String lastModifiedBy) 
	{
		this.lastModifiedBy = lastModifiedBy;
	}

	public DateTime getLastModifiedDate() 
	{
		return lastModifiedDate;
	}
	
	public void setLastModifiedDate(DateTime lastModifiedDate) 
	{
		this.lastModifiedDate = lastModifiedDate;
	}
	
	@Transient
	public boolean isNew() 
	{
		if (id == null) 
		{
			return true;
		} else 
		{
			return false;
		}
	}
	
	@Override
	public String toString() {
		return "Student [id=" + id + ", version=" + version + ", firstName="
				+ firstName + ", lastName=" + lastName + ", address=" + address
				+ ", phone=" + phone + ", email=" + email
				+ ", parentFirstName=" + parentFirstName + ", parentLastName="
				+ parentLastName + ", Create by: " + createdBy + ", Create date: " + createdDate
				+ ", Modified by: " + lastModifiedBy + ", Modified date: "
				+ lastModifiedDate + "]";
	}
}
